package org.wendu.wdoa.common.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.lang.reflect.Field;
import java.util.Map;

@Slf4j
public class CustomFilter extends UsernamePasswordAuthenticationFilter {



    @SneakyThrows //lombok提供，可以实现将方法中的异常自动转换包装为非受查异常
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

        //获得了这个类的私有属性postOnly反射对象
        Field postOnlyField = UsernamePasswordAuthenticationFilter.class.getDeclaredField("postOnly");
        postOnlyField.setAccessible(true); //设置属性可访问
        boolean postOnly = postOnlyField.getBoolean(this);//取本对象postOnly

        if (postOnly && !request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }


        if (request.getContentType().contains(MediaType.APPLICATION_JSON_VALUE)){

            StringBuilder builder = new StringBuilder();
            BufferedReader in = request.getReader();     //读到请求的json串
            String line = null;
            while ((line=in.readLine()) != null){

                if (builder.length() == 0)builder.append(line).append("\r\n");
                else builder.append("\r\n").append(line);
            }
            String jsonStr = builder.toString();
            log.debug("收到登录json数据:{}",jsonStr);
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String,String> map = objectMapper.readValue(jsonStr, Map.class);
            log.debug("json->map:{}",map);

            String username = map.get(getUsernameParameter());
            username = username != null ? username : "";
            username = username.trim();
            String password = map.get(getPasswordParameter());
            password = password != null ? password : "";
            UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
            this.setDetails(request, authRequest);
            return this.getAuthenticationManager().authenticate(authRequest);}
        else {
            super.attemptAuthentication(request,response);
        }
        return attemptAuthentication(request,response);
    }
}
